/*
 * Copyright 2008 Wilfred Springer
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.agilejava.javaone;

import java.io.IOException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.sun.org.apache.xpath.internal.XPathAPI;

/**
 * An {@link SessionCatalog} that loads its data online from the Cplan catalog.
 * 
 * @author Wilfred Springer
 * 
 */
public class CplanSessionCatalog extends AbstractSessionCatalog implements
        SessionCatalog {

    public CplanSessionCatalog(int nrThreads) {
        super(nrThreads);
    }

    private final static String XPATH_SESSIONS = "//body/center".replaceAll(
            "/", "/html:");


    private final static String ALL_SESSIONS_URL = "http://www28.cplan.com/cc191/sessions_catalog.jsp?ilc=191-1&ilg=english&isort=&isort_type=&is=yes&icriteria1=+&icriteria2=+&icriteria9=&icriteria8=&icriteria3=";

    /**
     * {@inheritDoc}
     * 
     * No caching whatsoever.
     */
    public List<Session> getSessions() {
        try {
            return loadSessions(loadDocument(new URL(ALL_SESSIONS_URL)));
        } catch (Exception e) {
            throw new DataAccessException("Failed to retrieve session data.", e);
        }
    }

    private List<Session> loadSessions(Node doc)
            throws ParserConfigurationException, IOException, SAXException,
            TransformerException {
        List<Session> sessions = new LinkedList<Session>();
        NodeList sessionNodes = XPathAPI
                .selectNodeList(
                        doc,
                        "//html:table[html:form[@action='srvcontroller']]/html:form/html:tr[position()>2]");
        logger.logSessionCount(sessionNodes.getLength());
        int total = sessionNodes.getLength();
        for (int i = 0; i < total; i++) {
            Node sessionNode = sessionNodes.item(i);
            Session session = new Session();
            session.setId(XPathAPI.eval(sessionNode,
                    "html:td[position()=1]/html:center/text()").toString());
            logger.logLoadingSession(session.getId(), i, total);
            session.setTitle(XPathAPI.eval(sessionNode,
                    "html:td[position()=2]//html:a/text()").toString());
            String detailsHref = XPathAPI.eval(sessionNode,
                    "html:td[position()=2]//html:a/@href").toString();
            session.setDetailsURL(extractURL(detailsHref));
            session.setType(getType(XPathAPI.eval(sessionNode,
                    "html:td[position()=3]/text()").toString()));
            addDetails(session);
            NodeList presenterNodes = XPathAPI.selectNodeList(sessionNode,
                    "html:td[position()=4]/html:a");
            for (int j = 0; j < presenterNodes.getLength(); j++) {
                Node presenterNode = presenterNodes.item(j);
                Presenter presenter = new Presenter();
                presenter.setName(XPathAPI.eval(presenterNode, "text()")
                        .toString());
                logger.logLoadingPresenter(presenter.getName());
                presenter.setDetailsURL(extractURL(XPathAPI.eval(presenterNode,
                        "@href").toString()));
                addDetails(presenter);
                session.getPresenters().add(presenter);
            }
            sessions.add(session);
        }
        return sessions;
    }

}
